# python中函数名使用小写字母和下划线方法。使用def定义方法
def sum_2(a, b):  # 形式参数
    """
        求和函数
    :param a:
    :param b:
    :return: a与b的和
    """
    return a + b


result = sum_2(9, 8)  # 实际参数
print("sum_2", result)


# 高版本python3.5之后，支持type hints，类型提示，定义函数入参和返回值类型
def sum_3(param1: int, param2: int) -> int:  # 形式参数
    """
        求和函数
    :param param1:
    :param param2:
    :return: a与b的和
    """
    return param1 + param2


result2: int = sum_3(9, 8)


# python支持默认参数，或者是缺省参数，默认参数必须放在参数列表的末尾
def power(x, n=2):  # n：默认参数，缺省参数
    return x ** n


a = power(4, 3)
b = power(5, 3)
c = power(6)
print("a = ", a)
print("b = ", b)
print("c = ", c)


def infos(name, age=24, gender='女'):
    return f"大家好，我叫{name} ，我今年{age}岁，我是一名{gender}生"


mia = infos('mia', 24, '女')
print("mia", mia)
lily = infos('lily')
print("lily", lily)
jack = infos('jack', gender='男')
print("jack", jack)


# 可变参数，使用*args，函数参数列表中，可变参数必须放在参数列表的末尾
def total(param1, *args):  # 可变参数
    print("param1:", param1, "*args:", args)
    total_sum = 0
    for i in args:
        total_sum += i * i
    return total_sum


result = total(0, 1, 2, 3, 4, 5, 6)
print("result: ", result)


# 字典参数，使用**kwargs，函数参数列表中，可变参数必须放在参数列表的末尾
def dict_function(param1, **kwargs):  # 可变参数，接收字典
    print("param1:", param1, "**kwargs:", kwargs)
    for k, v in kwargs.items():
        print(k, v)

my_dict = {'name': 'xiaoming', 'age': 18}
dict_function("test_param1", **my_dict)
dict_function("test_param1", name='xiaoming', age=18)

# 变量作用域
# 全局变量
num1 = 10  # 不可变数据类型
num2 = 20  # 不可变数据类型
list1 = [1, 2, 3, 4, 5]  # 可变数据类型


def test_function():
    global num1  # 声明在f中使用的num1是全局变量num1
    num1 = 20
    num2 = 30
    num3 = 40
    list1[2] = 8
    print('在函数f中打印num1的值', num1)
    print('在函数f中打印num2的值', num2)
    print('在函数f中打印num3的值', num3)
    print('在函数f中打印list1的值', list1)


test_function()
print('在函数f执行后打印num1的值', num1)
print('在函数f执行后打印num2的值', num2)
# print('在函数f执行后打印num3的值', num3) # num3是局部变量，在函数f执行后，num3就不存在了
print('在函数f执行后打印list1的值', list1)
